﻿using System;
using System.Xml;
using DarkAngels.WoW.Library.Armory.Character.tabs;
using DarkAngels.WoW.Library.Interfaces;
using DarkAngels.WoW.Library.Network;
using guild = DarkAngels.WoW.Library.Armory.Guild;

namespace DarkAngels.WoW.Library.Armory.Character
{
    public class Character : AbstractDataClass
    {
        #region Properties
        public String CharacterName
        {
            get;
            internal set;
        }
        public Int32 Level
        {
            get;
            internal set;
        }
        public Int32 AchievementPoints
        {
            get;
            private set;
        }
        public String RealmName
        {
            get;
            internal set;
        }
        public String Prefix
        {
            get;
            private set;
        }
        public String Suffix
        {
            get;
            private set;
        }
        public String BattleGroup
        {
            get;
            private set;
        }
        public String CharUrl
        {
            get;
            internal set;
        }
        public String GuildName
        {
            get;
            internal set;
        }
        public String GuildUrl
        {
            get;
            internal set;
        }
        public Int32 GuildRank
        {
            get;
            internal set;
        }
        public Gender Gender
        {
            get;
            internal set;
        }
        public Int32 GenderId
        {
            get;
            internal set;
        }
        public Class Class
        {
            get;
            internal set;
        }
        public Int32 ClassId
        {
            get;
            internal set;
        }
        public Faction Faction
        {
            get;
            internal set;
        }
        public Int32 FactionId
        {
            get;
            internal set;
        }
        public Race Race
        {
            get;
            internal set;
        }
        public Int32 RaceId
        {
            get;
            internal set;
        }
        private guild.Guild m_guild = null;
        public guild.Guild Guild
        {
            get
            {
                if (this._Loaded && (GuildUrl.Length > 0 || GuildName.Length > 0) && m_guild == null)
                {
                    m_guild = new guild.Guild(GuildName, RealmName, Region, Provider);
                    m_guild.Load();
                }
                return m_guild;
            }
            internal set
            {
                m_guild = value;
            }
        }
        private System.Drawing.Image m_avatar = null;
        public System.Drawing.Image Avatar
        {
            get
            {
                if (m_avatar == null)
                {
                    string avatarFolder = "";
                    if (Level < 60)
                    {
                        avatarFolder = "-default";
                    }
                    else if (Level >= 60 && Level < 70)
                    {
                        avatarFolder = "";
                    }
                    else if (Level >= 70 && Level < 80)
                    {
                        avatarFolder = "-70";
                    }
                    else if (Level >= 80 && Level < 90)
                    {
                        avatarFolder = "-80";
                    }
                    m_avatar = Provider.GetImage(BuildUri(String.Format("images/portraits/wow{0}/{1}-{2}-{3}.gif", avatarFolder, GenderId, RaceId, ClassId)));
                }
                return m_avatar;
            }
        }
        private System.Drawing.Image m_racialIcon = null;
        public System.Drawing.Image RacialIcon
        {
            get
            {
                if (m_racialIcon == null)
                {
                    m_racialIcon = Provider.GetImage(BuildUri(String.Format("images/icons/race/{0}-{1}.gif", RaceId, GenderId)));
                }
                return m_racialIcon;
            }
        }
        private System.Drawing.Image m_classIcon = null;
        public System.Drawing.Image ClassIcon
        {
            get
            {
                if (m_classIcon == null)
                {
                    m_classIcon = Provider.GetImage(BuildUri(String.Format("images/icons/class/{0}.gif", ClassId)));
                }
                return m_classIcon;
            }
        }

        #region Character tabs
        private CharacterTab m_charInfo = null;
        public CharacterTab CharacterInfo
        {
            get
            {
                if (m_charInfo == null)
                {
                    m_charInfo = new CharacterTab(this);
                    m_charInfo.Load();
                }
                return m_charInfo;
            }
        }
        private ReputationTab m_reputationInfo = null;
        public ReputationTab ReputationInfo
        {
            get
            {
                if (m_reputationInfo == null)
                {
                    m_reputationInfo = new ReputationTab(this);
                    m_reputationInfo.Load();
                }
                return m_reputationInfo;
            }
        }
        private TalentsTab m_talents = null;
        public TalentsTab TalentsInfo
        {
            get
            {
                if (m_talents == null)
                {
                    m_talents = new TalentsTab(this);
                    m_talents.Load();
                }
                return m_talents;
            }
        }
        private AchievementTab m_achievements = null;
        public AchievementTab AchievementsInfo
        {
            get
            {
                if (m_achievements == null)
                {
                    m_achievements = new AchievementTab(this);
                    m_achievements.Load();
                }
                return m_achievements;
            }
        }
        private FeedTab m_feed = null;
        public FeedTab Feed
        {
            get
            {
                if (m_feed == null)
                {
                    m_feed = new FeedTab(this);
                    m_feed.Load();
                }
                return m_feed;
            }
        }
        #endregion

        /// <summary>
        /// Used to check if the character information has been loaded already
        /// </summary>
        internal Boolean _Loaded
        {
            get;
            private set;
        }
        #endregion

        #region Methods
        internal void _SetProperties(XmlNode characterInfo)
        {
            if (!_Loaded && characterInfo != null)
            {
                //set all properties
                CharUrl = characterInfo.Attributes["charUrl"].Value;
                Prefix = characterInfo.Attributes["prefix"].Value;
                Suffix = characterInfo.Attributes["suffix"].Value;
                Level = Int32.Parse(characterInfo.Attributes["level"].Value);
                AchievementPoints = Int32.Parse(characterInfo.Attributes["points"].Value);
                BattleGroup = characterInfo.Attributes["battleGroup"].Value;
                GuildName = characterInfo.Attributes["guildName"].Value;
                GuildUrl = characterInfo.Attributes["guildUrl"].Value;
                Gender = (Gender)Enum.ToObject(typeof(Gender), Int32.Parse(characterInfo.Attributes["genderId"].Value));
                GenderId = Int32.Parse(characterInfo.Attributes["genderId"].Value);
                Class = (Class)Enum.ToObject(typeof(Class), Int32.Parse(characterInfo.Attributes["classId"].Value));
                ClassId = Int32.Parse(characterInfo.Attributes["classId"].Value);
                Faction = (Faction)Enum.ToObject(typeof(Faction), Int32.Parse(characterInfo.Attributes["factionId"].Value));
                FactionId = Int32.Parse(characterInfo.Attributes["factionId"].Value);
                Race = (Race)Enum.ToObject(typeof(Race), Int32.Parse(characterInfo.Attributes["raceId"].Value));
                RaceId = Int32.Parse(characterInfo.Attributes["raceId"].Value);
                //make sure we can check if properties are already loaded
                _Loaded = true;
            }
        }

        public override void Load()
        {
            if (m_talents == null)
            {
                m_talents = new TalentsTab(this);
                m_talents.Load();
            }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Allows us to create a character object for fetching character specific information
        /// </summary>
        /// <param name="charName">A realm unique identifier for the character</param>
        /// <param name="realmName">The realm on which the character resides</param>
        /// <param name="region">The region in which the character resides</param>
        public Character(String charName, String realmName, ArmoryRegion region)
        {
            Region = region;
            RealmName = realmName;
            CharacterName = charName;
            Provider = new SimpleNetworking();

            Gender = Gender.NotSet;
            Class = Class.NotSet;
            Faction = Faction.NotSet;
            Race = Race.NotSet;
        }

        public Character(String charName, String realmName, ArmoryRegion region, INetworking network)
        {
            Region = region;
            RealmName = realmName;
            CharacterName = charName;
            Provider = network;

            Gender = Gender.NotSet;
            Class = Class.NotSet;
            Faction = Faction.NotSet;
            Race = Race.NotSet;
        }
        #endregion
    }
}
